﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace NNetSed
{
    class Program
    {
        static ushort _localPort;
        static ushort _remotePort;
        static string _remoteHost;
        static List<Rule> _rules = new List<Rule>();
        static List<Connection> _connections = new List<Connection>();

        static int Main(string[] args)
        {
            int result;

            result = ParseOptions(args);
            if (result != 0)
                return result;

            TcpListener tcpListener = new TcpListener(IPAddress.Any, _localPort);
            tcpListener.Start();
            while (true)
            {
                //blocks until a client has connected to the server
                TcpClient client = tcpListener.AcceptTcpClient();

                //create a thread to handle communication
                //with connected client
                Connection connection = new Connection(client, _remoteHost, _remotePort, _rules);
                _connections.Add(connection);
                connection.StartListening();
            }
        }

        static int ParseOptions(string[] args)
        {
            // Protocol
            if (string.Compare(args[0], "tcp", true) != 0)
            {
                Console.WriteLine("Only the TCP protocol is currently supported.");
                return 1;
            }

            // Local Port
            if (!ushort.TryParse(args[1], out _localPort))
            {
                Console.WriteLine("Invalid local port");
                return 1;
            }

            // Remote Host
            _remoteHost = args[2];

            // Remote Port
            if (!ushort.TryParse(args[3], out _remotePort))
            {
                Console.WriteLine("Invalid remote port");
                return 1;
            }

            // Rules
            for (int i = 4; i < args.Length; i += 2)
            {
                if (i + 1 >= args.Length)
                {
                    Console.WriteLine("Wrong number of arguments");
                    return 1;
                }

                Rule rule = new Rule();
                rule.SearchString = args[i];
                rule.ReplaceString = args[i + 1];
                _rules.Add(rule);
            }

            return 0;
        }

        //static void ExampleOptionsParser()
        //{
        //    int threadCount = 1;
        //    string usernameFile = null;
        //    List<string> passwordFiles = new List<string>();
        //    string proxyAddress = null;
        //    string outputFilePath = null;
        //    List<string> floatingArgs;

        //    var options = new CommonOptions();
        //    options.AddOption(
        //        "U|userlist=",
        //        "Path to a user list file.",
        //        v => usernameFile = v);
        //    options.AddOption(
        //        "P|passwordlist=",
        //        "Path to a password list or ”-” without the quotes for standard in (stdin).",
        //        v => passwordFiles.Add(v));
        //    options.AddOption<int>(
        //        "t|threads=",
        //        "Number of threads to use.",
        //        v => threadCount = v);
        //    options.AddOption(
        //        "o|output=",
        //        "A file to write the output to.",
        //        v => outputFilePath = v);
        //    options.AddOption(
        //        "x|proxy=",
        //        "A SOCKS proxy to use (e.g. 127.0.0.1:1080).",
        //        v => proxyAddress = v);

        //    if (!options.ParseOptions(args, out floatingArgs, 0, 0))
        //        return;

        //    if (usernameFile == null)
        //    {
        //        options.WriteOptionsErrorMessage(
        //          "Must specify at least one username list.");
        //        return;
        //    }
        //    if (passwordFiles.Count == 0)
        //    {
        //        options.WriteOptionsErrorMessage(
        //            "Must specify at least one password list.");
        //        return;
        //    }
        //    if (threadCount <= 0)
        //    {
        //        options.WriteOptionsErrorMessage(
        //            "The thread count must be a positive integer greater than zero.");
        //        return;
        //    }
        //}
    }
}
